/* eslint-disable */
let _Vue = null
/*
    组织结构：
        1. options => 记录new VueRouter时传入的参数
        2. data  => 记录当前 路由path, 响应式，当 path变化时，更新视图
        3. routeMap => 将传入的routes数组转化为 map, key为path, value 为对应的component

        插件机制：所以 必须要有install函数 install(vue)， 参数为vue

        constructor: 构造器
        createRouteMap: 
        createComponent: router-link router-view组件创建
        
*/

export default class VueRouter {
    static install(Vue) { // 安装
        // 1. 判断VueRouter是否已经被安装了
        if(VueRouter.install.installed) {
            return
        }
        VueRouter.install.installed = true
        // 2. 将传入的vue 赋值给全局 _vue 变量
        _Vue = Vue
        // 3. 将创建vue实例时传入的router 添加到vue实例上去 this.$router....
        // 使用mixin
        _Vue.mixin({
            beforeCreate() {
                if(this.$options.router) {
                    // this.$options 这个值，在VueRouter里面拿不到，只有在 mixin里面是可以拿到的
                    _Vue.prototype.$router = this.$options.router
                    // 此处的this为vue实例，为啥在这里初始化？只是为了拿到 vue实例吗
                    this.$options.router.init(_Vue)
                }
            },
        })
    }
    constructor(options) {
        this.$options = options
        this.data = _Vue.observable({ // 响应式
            current: '/', // 第一次时为 根路由,如何 添加#号
        })
        this.routerMap = {}
    }
    initEvent() {
        // window.addEventListener('popstate', (e) => {
        //     console.log(e, 'asdf', window.location)
        //     // 浏览器前进后台按钮 会触发popstate事件，此时 浏览器地址已经更新，但是页面还没有 重新渲染
        //     this.data.current = window.location.pathname
        // })
        window.addEventListener('hashchange', e => {
            this.data.current = window.location.hash.split('#')[1]
        })
    }
    init() {
        this.createRouteMap()
        this.initComponent(_Vue)
        this.initEvent()
    }
    createRouteMap() {
        // 遍历routes ，将其存入 routeMap中
        this.$options.routes.forEach(route => {
            this.routerMap[route.path] = route.component
        })
    }

    // initComponent
    initComponent(Vue) {
        // <router-link to="home"></router-link>
        console.log(this, 'this11')
        Vue.component('router-link', {// 在runtime-only模式下，无法使用template模板预编译方法
            props: {
                to: String,
            },
            // template:  '<a :href="to"><slot></slot></a>',
            render: function(h) {
                // 此处使用function ,因为 里面this执行的是vue实例
                return h('a', {
                    attrs: {
                        href: this.to
                    }, 
                    on: {
                        click: this.clickHandler
                    }
                },
                [this.$slots.default], // 子节点
                )
            },
            methods: {
                clickHandler(e) {
                    // 修改浏览器地址栏地址
                    // history.pushState({}, '', this.to)
                    // hash 跳转路由
                    window.location.hash = this.to
                    this.$router.data.current = this.to
                    // 防止页面刷新
                    e.preventDefault();
                }
            }
        })
        const _that = this
        Vue.component('router-view', {// <router-view></router-view>
            render: function(h) {
                const component = _that.routerMap[_that.data.current]
                return h(component)
            }
        })
    }
}